import wx from 'weixin-js-sdk'
import { getWxInit, postMpLogin, getWxAppid,postBindingWxOpenId } from '@/common/request/api'
const jsApiList: Parameters<typeof wx.config>[0]['jsApiList']  = ['updateAppMessageShareData', 'updateTimelineShareData', 'chooseWXPay', 'getLocation']
import {
		useInit
	} from '@/common/stores'
import { objToUri, getWebBrowser,page } from '@/common/utils'
import type {MpShare} from './utils'
import type {WxPaymentParams} from '@/typings/utils'

interface PaymentParams {
	timeStamp : string
	nonceStr : string
	package : string
	paySign : string
}
export interface MpPaymentParams extends PaymentParams  {
	signType : 'MD5' | 'HMAC-SHA256' | 'RSA'
	orderInfo ?: Record<any, any>
}

export interface MpH5PaymentParams extends PaymentParams  {
	signType :  "SHA1" | "MD5"
	orderInfo ?: Record<any, any>
}




let initCode:string|null = null

const mpLogin = (param: { code: string }) => {
	let salt = getQueryString('salt')
	if (salt) {
		uni.setStorageSync('userSalt', salt)
	}
	let mpRedirect = uni.getStorageSync('mpRedirect')
	uni.removeStorageSync('mpRedirect')
	let hasBinding = getQueryString('binding')
	if(hasBinding){
		postBindingWxOpenId({
			code:param.code
		}).finally(() => {
			window.location.href = location.origin + location.pathname+'#/pages/splash'
		})
		return 
	}
	postMpLogin({
		...param,
		salt
	}).then(res => {
		try {
			initCode = param.code
			uni.setStorageSync('wxInitCode', initCode)
			let href = location.origin + location.pathname
			if (res.data.access_token) {
				uni.setStorageSync('token', res.data.access_token)
				if (mpRedirect) {
					let url = mpRedirect.url
					window.location.href = href + `#${url[0] === '/' ? '' : '/'}${url}`
					// if (mpRedirect.type === '2') {
					// 	uni.redirectTo({
					// 		url
					// 	})
					// } else {
					// 	uni.navigateTo({
					// 		url
					// 	})
					// }
				} else {
					window.location.href = href+'#/pages/splash'
				}
				// store.dispatch('getUserInfo')
				// store.dispatch('getCart')
			} else {
				let params:{
					id?:string
					salt?:string
				} = {
					id: res.data.openid
					
				}
				if (salt) {
					params['salt'] = salt
				}
				window.location.href = href + `#/pages/public/account/binding?${objToUri(params)}`
				// uni.navigateTo({
				// 	url: `/pages/public/account/binding?id=${res.data.openid}`
				// })
			}

		} catch (e) { }
	}).catch(() => {
		location.href = location.href.replace(location.search,'')
	})
}

export const getQueryString = (name:string) => {
	// 微信授权返回的code是拼接在location.pathname之后的,与普通html一致,参数是在location.search
	// hash模式下的路由参数是拼接在location.hash之后的
	// 所以获取微信授权返回的参数要从location.search获取
	let r = window.location.search.substr(1).split('&')
	let urlObject:Record<string,string> = {}
	if (r.length > 0) {
		for (var i = 0, len = r.length; i < len; i++) {
			var urlItem = r[i]
			var item = urlItem.split('=')
			urlObject[item[0]] = item[1]
		}

		return urlObject[name]
	}
	return null
}
export const getShareLink = () => {
	let origin = location.origin + location.pathname
	let href = location.hash.split('#')
	// #ifdef PRIVATE
	try {
		return origin + `?tenant=${uni.getStorageSync('tenant')}&storeId=${uni.getStorageSync('storeId')}#` + href[1]
	} catch (e) { }
	// #endif

	// #ifdef SUBSCRIPTION
	try {
		return origin + `?tenant=${uni.getStorageSync('tenant')}#` + href[1]
	} catch (e) { }
	// #endif
	return origin
}
/**
 * 调起微信支付
 * @param {params} 支付参数
 * timestamp支付签名时间戳
 * nonceStr支付签名随机串
 * package统一支付接口返回的prepay_id参数值，提交格式如：prepay_id=\*\*\*）
 * signType签名方式，默认为'SHA1'，使用新版支付需传入'MD5'
 * paySign支付签名
 * @param {signature} //签名 用于权限注入使用
 * @param {successCallBack} 成功回调
 * @param {failCallBack} 失败回调
 * @param {cancelBack} 取消回调
 */
// 公众号模式下的支付
// #ifdef SUBSCRIPTION || PRIVATE
export const wxPay = (params:MpH5PaymentParams, successCallBack:WxPaymentParams['success'], failCallBack:WxPaymentParams['fail'], cancelBack:WxPaymentParams['complete'] = () => { }) => {
	wx.ready(() => {
		wx.chooseWXPay({
			timestamp: Number(params.timeStamp),
			nonceStr: params.nonceStr,
			package: params.package,
			signType: params.signType,
			paySign: params.paySign,
			success: successCallBack,
			fail: failCallBack,
			cancel: cancelBack
		})
	})
}
// #endif

/**
 * 分享给朋友
 */
export const wxAppMessageShareData = ({ title, desc = '', link = '', imgUrl }:MpShare, success = () => { }, cancel = () => { }) => {
	wx.ready(() => {
		wx.updateAppMessageShareData({
			title,
			desc: desc,
			link,
			imgUrl,
			success,
			cancel
		})
	})
}
/**
 * 分享到朋友圈
 */
export const wxTimelineShareData = ({ title, desc = '', link = '', imgUrl }:MpShare, success = () => { }, cancel = () => { }) => {
	wx.ready(() => {
		wx.updateTimelineShareData({
			title,
			desc: desc,
			link,
			imgUrl,
			success,
			cancel
		})
	})
}

let isSetConfig = true

const initLogin = (redirect?: {
	url:string,
	type:string
},binding?:boolean) => {
	getWxAppid({
		currentUrl: location.href.split('#')[0]
	}).then(res => {

		let { appId, componentAppid } = res

		let code = getQueryString('code')
		let wxInitCode = uni.getStorageSync('wxInitCode')
		wxInitCode && (initCode = wxInitCode)
		let isReLogin = false
		if(!getQueryString('binding')){
			if (initCode && initCode === code) {
				// 链接上有code且code是最近获得的code，则需判断是否有token，有则代表已登录，无需继续，无则代表code已失效，重新登录
				if(uni.getStorageSync('token')){
					return
				}else{
					 isReLogin = true
				}
			}
		}
		
		
		const initStore = useInit()
		if (!code||isReLogin) {
			// 链接无code参数或需要重新登录，则跳转到微信授权页面
			let href = location.href
			if(code||href.indexOf(location.origin+location.pathname+'?') > -1){
				// 在有code或href上有携带search的情况下，清除链接上的search参数，否则redirect_uri数据有误
				href = href.replace(location.search,'')
			}
			let redirect_uri = href.split('/#')[0]
			
			// 链接有邀请码则缓存邀请码
			let salt = getQueryString('salt') || uni.getStorageSync('userSalt')
			if (salt||binding) {
				if(binding){
					redirect_uri = redirect_uri + `${redirect_uri.indexOf('?') > -1 ? '&':'?'}binding=1`
				}
				if(salt){
					redirect_uri = redirect_uri + `${redirect_uri.indexOf('?') > -1 ? '&':'?'}salt=${salt}`
				}
				
				redirect_uri = encodeURIComponent(redirect_uri)
			} else{
				redirect_uri = encodeURIComponent(redirect_uri+(redirect_uri.indexOf('#/') > -1 ? '' :'/'))
			}
			// 有redirect参数或当前路由路径非tabbar页面，则缓存至mpRedirect，调用mpLogin后会跳转至缓存的mpRedirect指定的页面
			uni.removeStorageSync('mpRedirect')
			
			if (redirect) {
				uni.setStorageSync('mpRedirect', redirect)
			} else {
				let pagePath = page()
				
				if (pagePath === '/pages/tabbar/index') {
					uni.setStorageSync('tabbarPageIndex', initStore.tabbarPageIndex)
				} else {
					if(!['/pages/public/account/register'].includes(pagePath)){
						uni.setStorageSync('mpRedirect', {
							url: location.hash.split('#')[1] || pagePath,
							type: 1
						})
					}
					
				}
			}
			let url =
				'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
				appId +
				'&redirect_uri=' +
				redirect_uri +
				'&response_type=code&scope=snsapi_userinfo&state=1&component_appid=' +
				componentAppid +
				'&connect_redirect=1#wechat_redirect'

			window.location.href = url
		} else {
			
			let index = uni.getStorageSync('tabbarPageIndex')
			if (location.hash === '#/pages/tabbar/index' && index) {
				initStore.setTabbarPageIndex(index)
				uni.removeStorageSync('tabbarPageIndex')
			}
			mpLogin({ code })
		}
	})
}

type WxLocationData = {
	latitude: number
	longitude: number
}

export const wxGetLocation = ():Promise<WxLocationData> =>
	new Promise((resolve, reject) => {
		wx.ready(() => {
			wx.getLocation({
				type: 'gcj02', // 默认为wgs84的 gps 坐标，如果要返回直接给 openLocation 用的火星坐标，可传入'gcj02'
				success: (res:WxLocationData) => resolve(res),
				fail: (err:any) => reject(err)
			})
		})

	})

/**
 * 初始化
 */
export default async function init(isLogin = true, redirect?: {
	url:string,
	type:string
},binding?:boolean) {
	try {
		// 一个html生命周期内只调用一次wx.config即可,短时间多次调用会导致后端返回的签名不正确
		isSetConfig &&
			getWxInit({
				currentUrl: location.href.split('#')[0]
			}).then(res => {
				let { appId, timeStamp, nonceStr, signature, componentAppid } = res

				// #ifdef SUBSCRIPTION
				if (!getWebBrowser('wx')) {
					res.domain && (window.location.href = `${res.domain}/#${location.hash.split('#')[1]}`)
				}
				// #endif

				wx.config({
					debug: false,
					appId, // 必填，公众号的唯一标识
					timestamp: Number(timeStamp), // 必填，生成签名的时间戳
					nonceStr, // 必填，生成签名的随机串
					signature, // 必填，签名
					jsApiList // 必填，需要使用的JS接口列表
				})
				isSetConfig = false

			})
		if(binding||getQueryString('binding')){
			initLogin(undefined,true)
			return 
		}
		if (isLogin) {
			initLogin(redirect)
		}
	} catch (e) {
		console.log(e)
		initCode = null
		uni.removeStorageSync('wxInitCode')
	}
}


